<?php
/*
 * xsorter
 *
 * Refbook sorter
 *
 * @version:	0.1
 * @package:	radcore
 * @update:		30 jan 2011
 * @link:		http://radiance-project.com/
 * @link:		http://qfox.ru/
 * @author:		alex <alex@qfox.ru> yaroshevich
 * @copyright:	(c) 2008-2011 radiance framework
 */


class xsorter {

	protected $directions_rotation = array(
		'+', '-'
		);

	protected $directions_signs = array(
		'+' => '↓',
		'-' => '↑'
		);

	public function __construct($columns = null, $key = null, $method = null)
	{
		if (!is_null($columns))
			$this->set_columns($columns);

		if (is_string($key) && !empty($key))
			$this->key = $key;

		if (is_string($method) && !empty($method))
			$this->method = $method;
	}

	protected $key = 'order';
	protected $method = 'get';

	protected $columns = null;
	protected $sorting = null;

	protected $default_sorting = null;

	public function set_columns($cols)
	{
		$this->columns = array();
		foreach( $cols as $k => $col )
		{
			if (is_array($col))
			// col is array with order
			{
				if (!isset($col['order']) || (!$col['order']))
					continue;

				$col['text'] = isset($col['text']) && mb_strlen($col['text']) > 2
					? $col['text']
					: ( isset($col['title']) && mb_strlen($col['title']) > 2
						? $col['title']
						: ( isset($col['html']) && mb_strlen(strip_tags($col['html'])) > 2
							? html_escape(strip_tags($col['html']))
							: $k ) );

				$col['order'] = $col['order'] === true ? $k.'+' : $col['order'];
			}
			elseif (is_string($col))
			{
				$col = array( 'text' => $col, 'order' => $k.'+' );
			}
			// col is invalid
			else continue;

			$this->columns[$k] = $col;
		}
	}

	public function set_directions($a)
	{
		$this->directions_rotation = array_keys( $a );
		$this->directions_signs = $a;
	}

	public function set_default($default)
	{
		$this->default_sorting = $default;
	}

	public function parse_sorting()
	{
		if (!is_null($this->sorting))
			return;

		$sorts = reqi()->{"{$this->method}_{$this->key}"};
		if (empty($sorts))
			$sorts = $this->default_sorting;

		$this->sorting = array();
		foreach (explode(',',$sorts) as $i) {
			$o = trim( $i, '+- ' );
			$d = substr( $i, -1, 1 ) == '-' ? '-' : '+';
			if (isset($this->columns[$o]))
				$this->sorting[$o] = $d;
		}
	}

	public function get_columns()
	{
		return $this->columns;

		// order column[s] and direction
/*		$o = mb_strtolower( (string)( pick( reqi()->g_order, $this->order ) ) );
		if (isset($this->columns[$o]['order']) && $this->columns[$o]['order'],','.trim($o,'+-').',')===false)
			$o = $this->order;
		$d = substr( $o, -1, 1 ) == '-' ? '-' : '+';
		$o = trim($o,'+-');
		$order = $o.$d;*/
	}

	public function apply_direction($order,$d)
	{
		return $d == '+' ? $order : $this->next_direction( $order );
	}

	/**
	 * Checks for column in current query
	 */
	public function is_sorting($col)
	{
		$this->parse_sorting();
		return isset($this->sorting[$col]);
	}

	public function is_sortable($col)
	{
		return isset($this->columns[$col]['order']) && !empty($this->columns[$col]['order']);
	}

	/**
	 * Returns pseudo column with direction
	 */
	public function get_sorting($col)
	{
		return $col . $this->get_direction($col);
	}

	/**
	 * Returns pseudo column with next direction
	 */
	public function get_next_sorting($col)
	{
		//var_dump( $col, $this->get_next_direction($col), $this->sorting, $this->columns ); die;
		return $col . $this->get_next_direction($col);
	}

	/**
	 * Returns current direction for pseudo column
	 */
	public function get_direction($col)
	{
		$this->parse_sorting();

		$r = isset($this->sorting[$col])
			? $this->sorting[$col]
			: ( isset($this->columns[$col])
				? substr($this->columns[$col]['order'],0,-1)
				: null );

		if (!$r || strlen($r)!=1 || !in_array($r,$this->directions_rotation))
			return '+';

		return $r;
	}

	/**
	 * Return next direction for pseudo column
	 */
	public function get_next_direction($col)
	{
		$order = $this->get_direction($col);

		return $this->is_sorting($col)
			? $this->next_direction($order)
			: $order;
	}

	/**
	 * Returns icon for direction (or column)
	 */
	public function get_direction_sign($col)
	{
		$d = in_array($col,$this->directions_rotation)
			? $col
			: $this->get_direction($col);

		return $this->directions_signs[$d];
	}



	/**
	 * Calculates next direction for pseudo column
	 */
	protected function next_direction($order)
	{
		$protation = $rotation = $this->directions_rotation;
		array_unshift( $protation, array_pop($protation) );

		return strtr( $order, array_combine( $rotation, $protation ) );
	}



	/**
	 * Returns current pseudo order for hrefs
	 */
	public function get_href_order($col)
	{
		return $this->is_sorting($col)
			? $this->get_next_sorting($col)
			: $this->get_sorting($col);
	}

	/**
	 * Returns compiled $order for model
	 */
	public function get_order()
	{
		$this->parse_sorting();

		$r = '';

		foreach ($this->sorting as $o => $d)
			$r .= $this->apply_direction($this->columns[$o]['order'],$d) . ',';

		$r = substr($r,0,-1);

		if (!is_string($r))
			$r = '';

		return $r;
	}
}

